﻿using System;

namespace NanoMvvm
{
    internal static class WeakEventListener
    {
        public static Action<TSender, TArgs> Wrap<TSender, TArgs>(Action<TSender, TArgs> eventHandler, Action<Action<TSender, TArgs>> deregisterAction)
            where TSender : class
            where TArgs : EventArgs
        {
            var wehc = new WeakEventHandlerContainer<TSender, TArgs>(eventHandler);

            Action<TSender, TArgs> handler = null;

            handler = delegate(TSender sender, TArgs args)
            {
                if (wehc.IsTargetAlive)
                {
                    wehc.Invoke(sender, args);
                }
                else
                {
                    deregisterAction(handler);
                }
            };

            return handler;
        }

        public static EventHandler Wrap(EventHandler eventHandler, Action<EventHandler> deregisterAction)
        {
            var wehc = new WeakEventHandlerContainer<object, EventArgs>(new Action<object, EventArgs>(eventHandler));

            EventHandler handler = null;

            handler = delegate(object sender, EventArgs args)
            {
                if (wehc.IsTargetAlive)
                {
                    wehc.Invoke(sender, args);
                }
                else
                {
                    deregisterAction(handler);
                }
            };

            return handler;
        }

        public static EventHandler<TArgs> Wrap<TArgs>(EventHandler<TArgs> eventHandler, Action<EventHandler<TArgs>> deregisterAction) 
            where TArgs : EventArgs
        {
            var wehc = new WeakEventHandlerContainer<object, TArgs>(new Action<object, TArgs>(eventHandler));

            EventHandler<TArgs> handler = null;

            handler = delegate(object sender, TArgs args)
            {
                if (wehc.IsTargetAlive)
                {
                    wehc.Invoke(sender, args);
                }
                else
                {
                    deregisterAction(handler);
                }
            };

            return handler;
        }
    }
}